/*
 *
 * Copyright (C) 2012 Walter Lütgenau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package offset.nodes.server.html.model;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/**
 *
 * @author Walter Luetgenau
 */
public class CSSFilter extends InputStream {
    String line = "";
    int pos = 0;
    BufferedReader reader = null;
    
    public static final double POINTSIZE_FACTOR = 1.42;
    double factor = POINTSIZE_FACTOR;
    
    /** Creates a new instance of CSSFilter */
    public CSSFilter(InputStream in) {
        reader = new BufferedReader( new InputStreamReader( in ));
    }
    
    protected String updatePointSize( String property ) throws IOException {
        StringBuffer value = new StringBuffer();
        for( int i=0; i<property.length(); i++) {
            if ( Character.isDigit(property.charAt(i)))
                value.append(property.charAt(i));            
        }
        int size = 0;
        try {
            size = Integer.parseInt( value.toString() );
        }
        catch( NumberFormatException e) {
            throw new IOException(e.getMessage());
        }
        
        size = (int) ((double) size*factor);
        
        return ""+size + "pt";        
    }

    protected String updatePointSizes(String property) throws IOException {
        StringBuilder result = new StringBuilder();
        String[] propertyValues = property.split(" ");

        for (int i = 0; i < propertyValues.length; i++) {
            if ((i == 0 || i == propertyValues.length - 1) && propertyValues[i].length() == 0)
                continue;

            result.append(updatePointSize(propertyValues[i]) + " ");
        }

        return result.toString();
    }
    
    protected String useBrowserSettings(String in) throws IOException {
        StringBuffer buf = new StringBuffer();
        StringTokenizer parser = new StringTokenizer(line, ":;", true);
        while( parser.hasMoreTokens()) {
            String token = parser.nextToken();
            if ( token.endsWith("pt"))
                token = updatePointSizes(token);
            
            buf.append(token);
        }
        
        return buf.toString();
    }
    
    protected void nextLine() throws IOException {
        line = reader.readLine();
        if ( line == null)
            return;
        
        line = useBrowserSettings(line)+"\r\n";
        pos = 0;
    }

    public int read() throws IOException {
        if ( line == null )
            return -1;
        
        if ( pos >= line.length())
            nextLine();
        
        if ( line == null)
            return -1;
        
        return (int) line.charAt(pos++);
    }

    public void setFactor(double factor) {
        this.factor = factor;
    }
    
    public static void main(String[] arguments) throws Exception {
        String test = ".info {\n " +
    "background-image: url(/nodes/registry/jcr:system/nodes/resources/images/info.png);\n" +
    "background-repeat: no-repeat;\n" +
    "background-position: 9pt 9pt;\n" +
    "padding-top:18pt;\n" +
    "padding-left: 60pt;\n" +
    "padding-bottom:9pt;\n" +
    "background-color:#C9E3F4;\n" +
    "border-radius: 1em;\n" +
    "box-shadow: gray 0.5em 0.5em 0.3em;\n" +
"};";
        ByteArrayInputStream in = new ByteArrayInputStream(test.getBytes());

        CSSFilter filter = new CSSFilter(in);
        
        byte[] buf = new byte[4096];
        int count = filter.read(buf);
        in.close();        
        System.out.print(new String(buf, 0, count));
    }
    
}
